(function ($, window, document, undefined) {
	var OnePageNav = function (elem, options) {
		this.elem = elem;
		this.$elem = $(elem);
		this.options = options;
		this.metadata = this.$elem.data('plugin-options');
		this.$win = $(window);
		this.sections = {};
		this.didScroll = false;
		this.$doc = $(document);
		this.docHeight = this.$doc.height()
	};
	OnePageNav.prototype = {
		defaults: {
			navItems: 'a',
			currentClass: 'current',
			changeHash: false,
			easing: 'swing',
			filter: '',
                        //table导航的高度
                        tableHeight: 50,
			scrollSpeed: 750,
			scrollThreshold: 0.1,
			begin: false,
			end: false,
			scrollChange: false
		},
		init: function () {
			this.config = $.extend({},
				this.defaults, this.options, this.metadata);
			this.$nav = this.$elem.find(this.config.navItems);
			if (this.config.filter !== '') {
				this.$nav = this.$nav.filter(this.config.filter)
			}
			this.$nav.on('click.onePageNav', $.proxy(this.handleClick, this));
			this.getPositions();
			this.bindInterval();
			this.$win.on('resize.onePageNav', $.proxy(this.getPositions, this));
			return this
		},
		adjustNav: function (self, $parent) {
			self.$elem.find('.' + self.config.currentClass).removeClass(self.config.currentClass);
			$parent.addClass(self.config.currentClass)
		},
		bindInterval: function () {
			var self = this;
			var docHeight;
			self.$win.on('scroll.onePageNav',
				function () {
					self.didScroll = true
				});
			self.t = setInterval(function () {
				docHeight = self.$doc.height();
				if (self.didScroll) {
					self.didScroll = false;
					self.scrollChange()
				}
				if (docHeight !== self.docHeight) {
					self.docHeight = docHeight;
					self.getPositions()
				}
			},
				250)
		},
		getHash: function ($link) {
			return $link.attr('href').split('#')[1]
		},
		getPositions: function () {
			var self = this;
			var linkHref;
			var topPos;
			var $target;
			self.$nav.each(function () {
				linkHref = self.getHash($(this));
				$target = $('#' + linkHref);
				if ($target.length) {
					topPos = $target.offset().top;
					self.sections[linkHref] = Math.round(topPos)
				}
			})
		},
		getSection: function (windowPos) {
			var returnValue = null;
			var windowHeight = Math.round(this.$win.height() * this.config.scrollThreshold);
			for (var section in this.sections) {
				if ((this.sections[section] - windowHeight) < windowPos) {
					returnValue = section
				}
			}
			return returnValue
		},
		handleClick: function (e) {
			var self = this;
			var $link = $(e.currentTarget);
			var $parent = $link.parent();
			var newLoc = '#' + self.getHash($link);
			if (!$parent.hasClass(self.config.currentClass)) {
				if (self.config.begin) {
					self.config.begin()
				}
				self.adjustNav(self, $parent);
				self.unbindInterval();
				self.scrollTo(newLoc,
					function () {
						if (self.config.changeHash) {
							window.location.hash = newLoc
						}
						self.bindInterval();
						if (self.config.end) {
							self.config.end()
						}
					})
			}
			e.preventDefault()
		},
		scrollChange: function () {
			var windowTop = this.$win.scrollTop();
			var position = this.getSection(windowTop);
			var $parent;
			if (position !== null) {
				$parent = this.$elem.find('a[href$="#' + position + '"]').parent();
				if (!$parent.hasClass(this.config.currentClass)) {
					this.adjustNav(this, $parent);
					if (this.config.scrollChange) {
						this.config.scrollChange($parent)
					}
				}
			}
		},
		scrollTo: function (target, callback) {
			var offset = $(target).offset().top;
			$('html, body').animate({
                                //减去的是为table导航的高度
				scrollTop: offset - this.config.tableHeight
			},
				this.config.scrollSpeed, this.config.easing, callback)
		},
		unbindInterval: function () {
			clearInterval(this.t);
			this.$win.unbind('scroll.onePageNav')
		}
	};
	OnePageNav.defaults = OnePageNav.prototype.defaults;
	$.fn.onePageNav = function (options) {
		return this.each(function () {
			new OnePageNav(this, options).init()
		})
	}
})(jQuery, window, document);